package com.kakarote.examine.controller;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.kakarote.common.log.annotation.OperateLog;
import com.kakarote.common.log.entity.OperationLog;
import com.kakarote.common.log.entity.OperationResult;
import com.kakarote.common.log.enums.BehaviorEnum;
import com.kakarote.common.log.enums.OperateObjectEnum;
import com.kakarote.common.log.enums.OperateTypeEnum;
import com.kakarote.core.common.Result;
import com.kakarote.core.common.enums.SystemCodeEnum;
import com.kakarote.core.entity.BasePage;
import com.kakarote.core.utils.UserCacheUtil;
import com.kakarote.examine.entity.BO.ExamineDelegatePageBO;
import com.kakarote.examine.entity.PO.ExamineDelegate;
import com.kakarote.examine.service.IExamineDelegateService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;

import static com.kakarote.common.log.enums.ApplyEnum.SYSTEM_SETTING;

/**
 * @author: admin
 * @version: v1.0
 * @date:2023/5/6
 */
@RestController
@RequestMapping("/examineDelegate")
@Api(tags = "审批委托接口")
public class ExamineDelegateController {
    @Autowired
    private IExamineDelegateService examineDelegateService;

    @PostMapping("/queryPageList")
    @ApiOperation(value = "查询流程委托列表")
    public Result<BasePage<ExamineDelegate>> queryPageList(@RequestBody ExamineDelegatePageBO search) {
        search.setPageType(1);
        LambdaQueryWrapper<ExamineDelegate> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ObjectUtil.isNotEmpty(search.getState()), ExamineDelegate::getState, search.getState());

        BasePage<ExamineDelegate> page = examineDelegateService.page(search.parse(), queryWrapper);

        page.getList().forEach(e -> {
            e.setDelegateUser(UserCacheUtil.getUserName(e.getDelegateUserId()));
            e.setTrusteeUser(UserCacheUtil.getUserName(e.getTrusteeUserId()));
            e.setCreateUser(UserCacheUtil.getUserName(e.getCreateUserId()));
        });

        return Result.ok(page);
    }

    @PostMapping("/save")
    @ApiOperation(value = "保存流程委托")
    @OperateLog(apply = SYSTEM_SETTING, object = OperateObjectEnum.DELEGATE_FLOW, type = OperateTypeEnum.SETTING, behavior = BehaviorEnum.SAVE)
    public Result save(@RequestBody @Validated ExamineDelegate examineDelegate) {

        if (examineDelegate.getStartTime().isBefore(LocalDateTime.now())) {
            return Result.error(400, "委托开始时间不能小于当前时间");
        }

        if (examineDelegate.getStartTime().isAfter(examineDelegate.getEndTime())) {
            return Result.error(400, "委托开始时间不能大于委托结束时间");
        }

        List<ExamineDelegate> list = examineDelegateService.lambdaQuery().eq(ExamineDelegate::getDelegateUserId, examineDelegate.getDelegateUserId())
                .eq(ExamineDelegate::getState, 1).list();
        if (!list.isEmpty()) {
            for (ExamineDelegate delegate : list) {
                String labels = delegate.getLabels();
                for (String label : labels.split(StrUtil.COMMA)) {
                    if (examineDelegate.getLabels().contains(label)) {
                        return Result.error(400, "设置模块已存在启用委托设置");
                    }
                }
            }
        }
        Integer count = examineDelegateService.selectCountByDate();
        examineDelegate.setNumber(DateUtil.format(new Date(), DatePattern.PURE_DATE_PATTERN) + "-" + String.format("%04d", count + 1));
        examineDelegateService.save(examineDelegate);

        OperationLog operationLog = new OperationLog();
        operationLog.setOperationObject(examineDelegate.getNumber());
        operationLog.setOperationInfo("新建委托流程：" + examineDelegate.getNumber());
        return OperationResult.ok(operationLog);
    }

    @PostMapping("/update")
    @ApiOperation(value = "修改流程委托")
    @OperateLog(apply = SYSTEM_SETTING, object = OperateObjectEnum.DELEGATE_FLOW, type = OperateTypeEnum.SETTING, behavior = BehaviorEnum.UPDATE)
    public Result update(@RequestBody @Validated ExamineDelegate examineDelegate) {
        if (examineDelegate.getDelegateId() == null) {
            return Result.error(SystemCodeEnum.SYSTEM_NO_VALID);
        }

        if (examineDelegate.getStartTime().isBefore(LocalDateTime.now())) {
            return Result.error(400, "委托开始时间不能小于当前时间");
        }

        if (examineDelegate.getStartTime().isAfter(examineDelegate.getEndTime())) {
            return Result.error(400, "委托开始时间不能大于委托结束时间");
        }

        ExamineDelegate currDelegate = examineDelegateService.getById(examineDelegate.getDelegateId());
        if (currDelegate.getState().equals(1)) {
            if (currDelegate.getStartTime().isBefore(LocalDateTime.now())) {
                return Result.error(400, "原委托开始时间小于当前时间,不允许修改");
            }
        }

        List<ExamineDelegate> list = examineDelegateService.lambdaQuery().eq(ExamineDelegate::getDelegateUserId, examineDelegate.getDelegateUserId())
                .ne(ExamineDelegate::getDelegateId, examineDelegate.getDelegateId())
                .eq(ExamineDelegate::getState, 1).list();
        if (!list.isEmpty()) {
            for (ExamineDelegate delegate : list) {
                String labels = delegate.getLabels();
                for (String label : labels.split(StrUtil.COMMA)) {
                    if (examineDelegate.getLabels().contains(label)) {
                        return Result.error(400, "设置模块已存在启用委托设置");
                    }
                }
            }
        }

        examineDelegateService.updateById(examineDelegate);

        OperationLog operationLog = new OperationLog();
        operationLog.setOperationObject(currDelegate.getNumber());
        operationLog.setOperationInfo("编辑委托流程：" + currDelegate.getNumber());
        return OperationResult.ok(operationLog);
    }

    @PostMapping("/setDelegateState/{delegateId}/{state}")
    @ApiOperation(value = "修改流程委托状态")
    @OperateLog(apply = SYSTEM_SETTING, object = OperateObjectEnum.DELEGATE_FLOW, type = OperateTypeEnum.SETTING)
    public Result setDelegateState(@PathVariable("delegateId") Long delegateId, @PathVariable("state") Integer state) {

        if (state == 1) {
            ExamineDelegate examineDelegate = examineDelegateService.getById(delegateId);
            List<ExamineDelegate> list = examineDelegateService.lambdaQuery().eq(ExamineDelegate::getDelegateUserId, examineDelegate.getDelegateUserId())
                    .eq(ExamineDelegate::getState, 1).list();
            if (!list.isEmpty()) {
                for (ExamineDelegate delegate : list) {
                    String labels = delegate.getLabels();
                    for (String label : labels.split(StrUtil.COMMA)) {
                        if (examineDelegate.getLabels().contains(label)) {
                            return Result.error(400, "设置模块已存在启用委托设置");
                        }
                    }
                }
            }
        }
        examineDelegateService.lambdaUpdate()
                .eq(ExamineDelegate::getDelegateId, delegateId)
                .set(ExamineDelegate::getState, state).update();


        ExamineDelegate examineDelegate = examineDelegateService.getById(delegateId);
        OperationLog operationLog = new OperationLog();
        operationLog.setOperationObject(examineDelegate.getNumber());
        if (state == 1) {
            operationLog.setBehavior(BehaviorEnum.START);
            operationLog.setOperationInfo("启用委托流程：" + examineDelegate.getNumber());
        } else {
            operationLog.setBehavior(BehaviorEnum.FORBID);
            operationLog.setOperationInfo("禁用委托流程：" + examineDelegate.getNumber());
        }
        return OperationResult.ok(operationLog);
    }


    @PostMapping("/updateDelegateStatus")
    @ApiOperation(value = "自动修改流程委托状态")
    public Result updateDelegateStatus() {
        examineDelegateService.updateDelegateStatus();
        return Result.ok();
    }

}
